package com.lilei.serialize;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.objenesis.strategy.StdInstantiatorStrategy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;

@Deprecated
public class KryoSerializer implements ISerializer {
    /*
        <!-- https://mvnrepository.com/artifact/com.esotericsoftware/kryo -->
        <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
            <version>4.0.0</version>
        </dependency>
     */
    private static final Kryo kryo = new Kryo();

    static {
        kryo.setReferences(false);
        kryo.setRegistrationRequired(false);
        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
    }

    @Override
    public <T> byte[] serialize(T obj) {
        kryo.register(obj.getClass());
        Output output = null;
        try {
            Field field = obj.getClass().getDeclaredField("serialVersionUID");
            field.setAccessible(true);
            long serialVersionUID = (long) field.get(null);
            output = new Output(new FileOutputStream(new File(serialVersionUID + "_kryo_" + obj.getClass().getName())));
            kryo.writeObject(output, obj);
            output.flush();
            output.close();
            return ByteBuffer.allocate((int) output.total()).get(output.getBuffer(), 0, (int) output.total()).array();
        } catch (FileNotFoundException | NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        Input input = null;
        try {
            Field field = clazz.getDeclaredField("serialVersionUID");
            field.setAccessible(true);
            long serialVersionUID = (long) field.get(null);
            input = new Input(new FileInputStream(new File(serialVersionUID + "_kryo_" + clazz.getName())));
            T obj = kryo.readObject(input, clazz);
            input.close();
            return obj;
        } catch (FileNotFoundException | NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}
